// 导入必要依赖（确保 api 实例和 ElMessage 已正确配置）
import type { BlockLike } from 'typescript';
import router from '../router'; // 引入路由实例，用于跳转登录页

import api from './api';
import { ElMessage } from 'element-plus';

// ------------------------------
// 1. 基础通用类型（与后端统一响应格式对齐）
// ------------------------------
// ------------------------------
// 4. 收藏相关接口
// ------------------------------
/** 收藏操作返回的业务数据类型 */
export interface CollectionBusinessData {
  collected: boolean;    // 当前收藏状态（true=已收藏，false=未收藏）
  collectionCount: number; // 最新收藏数
  postId: number;        // 被收藏帖子ID
}

/** 收藏接口的返回类型（顶层是 BaseResponse，data 是 CollectionBusinessData） */
export type CollectionRes = BaseResponse<CollectionBusinessData>;

/**
 * 帖子收藏/取消收藏
 * @param params 收藏参数（postId + isCollect）
 * @returns 收藏结果（含最新状态和收藏数）
 */
export const toggleCollection = async (params: {
  postId: number;        // 帖子ID（必传）
  isCollect: boolean;    // 收藏状态（true=收藏，false=取消收藏）
}): Promise<CollectionBusinessData> => {
  if (!params.postId || params.postId <= 0) {
    const errMsg = '帖子ID无效';
    ElMessage.error(errMsg);
    throw new Error(errMsg);
  }

  try {
    // 调用接口（路径：/collections/toggle，POST方法）
    const response = await api.post<BaseResponse<CollectionBusinessData>>(`/collections/toggle`, {
      postId: params.postId
    });

    if (response.code !== "0") {
      const errMsg = response.message || '收藏操作失败';
      ElMessage.error(errMsg);
      throw new Error(errMsg);
    }

    return response.data;
  } catch (error) {
    console.error(`toggleCollection 失败（ID: ${params.postId}）:`, error);
    throw error;
  }
};

/** 接口统一返回格式（严格匹配后端所有接口的顶层结构） */
export interface BaseResponse<T = any> {
  code: string;          // 状态码（"0" 表示成功，非"0"表示失败）
  message: string | null;// 提示信息（失败时非空）
  data: T;               // 业务数据（成功时的核心内容）
  requestId: string | null;// 请求ID（用于问题排查，可选）
  success: boolean;      // 成功标识（true/false，辅助判断）
  fail: boolean;         // 失败标识（与success相反，辅助判断）
}

/** 用户基础信息类型（通用，适用于帖子作者、评论者等） */
export interface UserBaseInfo {
  uid: number;           // 用户ID（必传）
  loginId: string;       // 登录账号（必传，nickname为null时用此显示）
  nickname: string | null;// 昵称（可选，可能为null）
  avatar: string | null; // 头像URL（可选，可能为null）
  intro: string;         // 个人简介（必传，默认"这个人很懒，没留下什么"）
}

// ------------------------------
// 2. 帖子相关类型（严格对齐后端 postRespDTO 结构）
// ------------------------------
/** 帖子类型（与后端返回的 postRespDTO 字段完全一致） */
export interface Post {
  id: number;            // 帖子ID（必传）
  uid: number;           // 发帖用户ID（必传）
  cateId: number;        // 分类ID（必传，如1=科技、2=艺术）
  cateName: string;      // 分类名称（必传，如"科技"）
  title: string;         // 帖子标题（必传，可能为短文本如"12"）
  content: string;       // 帖子内容（必传，可能为HTML或纯文本）
  media: string[];       // 帖子图片URL数组（必传，空数组时为[]）
  readCount: number;     // 阅读量（必传，默认0）
  commentCount: number;  // 评论数（必传，默认0）
  likeCount: number;     // 点赞数（必传，默认0）
  collectionCount: number;// 收藏数（必传，默认0）
  postTop: number;       // 置顶状态（必传，1=置顶，0=非置顶）
  createTime: string;    // 创建时间（必传，格式如"2025-09-05 21:25:52"）
  updateTime: string;    // 更新时间（必传，格式同上）
  user: UserBaseInfo;    // 发帖用户信息（必传，嵌套UserBaseInfo）
  canEdit: boolean;      // 是否可编辑（必传，true/false）
  canDelete: boolean;    // 是否可删除（必传，true/false）
  liked: boolean;        // 当前用户是否已点赞（必传，true/false）
  collected: boolean;    // 当前用户是否已收藏（必传，true/false）
}

/** 帖子列表接口的 data 字段类型（后端返回的分页数据） */
export interface PostsListBackendData {
  postRespDTOList: Post[]; // 帖子数组（核心数据）
  lastId: number;          // 最后一条帖子ID（用于分页续加载）
  total: number;    
  success:boolean       // 帖子总数（用于判断是否有更多）
}

/** 帖子列表接口的返回类型（顶层是 BaseResponse，data 是 PostsListBackendData） */
export type GetPostsRes = BaseResponse<PostsListBackendData>;

/** 分类类型（用于帖子筛选、分类列表展示） */
export interface Category {
  cateId: number;         // 分类ID（必传）
  cateName: string;       // 分类名称（必传，如"科技"）
  createTime: string;     // 创建时间（必传）
  updateTime: string;     // 更新时间（必传）
}

// ------------------------------
// 3. 评论/回复相关类型（对齐后端 Comment/Reply DTO 结构）
// ------------------------------
/** 回复类型（二级互动，嵌套在评论中） */
export interface Reply {
  id: number;            // 回复ID（必传）
  pid: number;           // 父评论ID（必传，指向所属评论）
  uid: number;           // 回复者ID（必传）
  toUid: number;         // 被回复者ID（必传，指向目标用户）
  postId: number;        // 所属帖子ID（必传）
  content: string;       // 回复内容（必传）
  likeCount: number;     // 回复点赞数（必传，默认0）
  status: number;        // 状态（必传，1=正常，0=删除）
  createTime: string;    // 创建时间（必传，格式如"2025-09-05 21:25:52"）
  updateTime: string;    // 更新时间（必传）
  userRespDTO: UserBaseInfo; // 回复者信息（必传）
  liked: boolean;        // 当前用户是否已点赞（必传，true/false）
}

/** 评论类型（一级互动，包含嵌套回复） */
export interface Comment {
  id: number;            // 评论ID（必传）
  pid: undefined | null; // 父评论ID（必传，一级评论为undefined/null）
  uid: number;           // 评论者ID（必传）
  toUid: undefined | null;// 被回复者ID（一级评论为undefined/null）
  postId: number;        // 所属帖子ID（必传）
  content: string;       // 评论内容（必传）
  likeCount: number;     // 评论点赞数（必传，默认0）
  status: number;        // 状态（必传，1=正常，0=删除）
  createTime: string;    // 创建时间（必传）
  updateTime: string;    // 更新时间（必传）
  userRespDTO: UserBaseInfo; // 评论者信息（必传）
  liked: boolean;        // 当前用户是否已点赞（必传）
  replies?: Reply[];     // 嵌套回复列表（可选，无回复时为undefined）
}

/** 评论列表接口的 data 字段类型（后端返回的分页数据） */
export interface CommentPageVO {
  commentVOS: Comment[]; // 评论数组（核心数据）
  lastTime: string;      // 最后一条评论时间（用于分页续加载）
  offset: number;        // 偏移量（用于分页）
  count: number;         // 评论总数（用于判断是否有更多）
}

/** 评论列表接口的返回类型（顶层是 BaseResponse，data 是 CommentPageVO） */
export type GetCommentsRes = BaseResponse<CommentPageVO>;

/** 点赞操作返回的业务数据类型（帖子/评论点赞通用） */
export interface LikeBusinessData {
  liked: boolean;        // 当前点赞状态（true=已赞，false=未赞）
  likeCount: number;     // 最新点赞数
  type: 0 | 1;           // 点赞类型（0=帖子，1=评论）
  objId: number;         // 被点赞对象ID
}

/** 点赞接口的返回类型（顶层是 BaseResponse，data 是 LikeBusinessData） */
export type LikeRes = BaseResponse<LikeBusinessData>;

/** 提交评论/回复的返回业务数据类型 */
export interface AddCommentBusinessData {
  comment: Comment | Reply; // 新增的评论/回复（根据pid判断）
  commentId?: number;       // 新增ID（可选，辅助确认）
}

/** 提交评论接口的返回类型 */
export type AddCommentRes = BaseResponse<AddCommentBusinessData>;

// ------------------------------
// 4. 帖子相关核心接口（与后端接口路径、参数完全对齐）
// ------------------------------
/**
 * 获取帖子列表（支持分类筛选、分页续加载）
 * @param params 筛选+分页参数
 * @returns 处理后的帖子列表+分页状态（含hasMore）
 */
export const getPosts = async (params?: {
  cateId?: number;       // 分类ID（可选，筛选特定分类）
  uid?: number;          // 用户ID（可选，筛选特定用户的帖子）
  size?: number;         // 每页条数（可选，默认10）
  lastId?: number | null;// 上一页最后一条ID（可选，续加载用）
}): Promise<{
  data: PostsListBackendData;
  hasMore: boolean;      // 计算后的"是否有更多"状态
}> => {
  try {
    // 1. 构造请求参数（默认值处理，避免传undefined）
    const requestParams = {
      size: params?.size || 10,
      lastId: params?.lastId ?? '', // 后端可能接受空字符串表示首次加载
      cateId: params?.cateId ?? '',
      uid: params?.uid ?? ''
    };
 
    // 2. 调用接口（指定返回类型为 GetPostsRes）
    const response = await api.get<GetPostsRes>('/posts', { params: requestParams });
    // 3. 判断接口是否成功（根据实际返回的数据格式调整）
    if (!response.success || response.code !== '0') {
      throw new Error(response?.message || '获取帖子列表失败');
    }

    // 4. 提取安全数据
    const safeBackendData = response.data || { postRespDTOList: [], lastId: 0, total: 0 };
    // 5. 计算hasMore（当前加载数 < 总数 → 有更多）
    const hasMore = safeBackendData.postRespDTOList.length < safeBackendData.total;

    // 6. 打印调试日志（便于排查分页问题）
    console.log('getPosts 成功:', {
      loadedCount: safeBackendData.postRespDTOList.length,
      total: safeBackendData.total,
      lastId: safeBackendData.lastId,
      hasMore
    });

    return { data: safeBackendData, hasMore };
  } catch (error) {
    // 7. 捕获网络错误（如超时、404等）
    console.error('getPosts 网络错误:', error);
    ElMessage.error(error.message);
    return {
      data: { postRespDTOList: [], lastId: 0, total: 0 },
      hasMore: false
    };
  }
};

/**
 * 获取帖子详情
 * @param postId 帖子ID（必传）
 * @returns 帖子完整信息（Post类型）
 * @throws 错误时抛出，由调用方处理降级逻辑
 */
export const getPostDetail = async (postId: number): Promise<Post> => {
  if (!postId || postId <= 0) {
    const errMsg = '帖子ID无效（必须为正整数）';
    ElMessage.error(errMsg);
    throw new Error(errMsg);
  }

  try {
    // 1. 调用接口（路径：/public/posts/{postId}）
    // 由于拦截器配置，response已经是请求体json对象，不需要再.data
    const response = await api.get<BaseResponse<Post>>(`/public/posts/${postId}`);

    // 2. 判断接口成功与否
    if (!response?.success || response?.code !== '0') {
      const errMsg = response?.message || `获取帖子详情失败（ID: ${postId}）`;
      ElMessage.error(errMsg);
      throw new Error(errMsg);
    }

    // 3. 兜底防止data为undefined
    const postData = response?.data;
    if (!postData) {
      const errMsg = `帖子详情数据为空（ID: ${postId}）`;
      ElMessage.error(errMsg);
      throw new Error(errMsg);
    }

    return postData;
  } catch (error) {
    console.error(`getPostDetail 失败（ID: ${postId}）:`, error);
    throw error; // 抛出错误，让调用方（如PostDetail.vue）处理降级
  }
};

/**
 * 帖子点赞/取消点赞
 * @param params 点赞参数（postId + isLike）
 * @returns 点赞结果（含最新状态和点赞数）
 */
export const likePost = async (params: {
  postId: number;        // 帖子ID（必传）
  isLike: boolean;       // 点赞状态（true=点赞，false=取消）
}): Promise<LikeBusinessData> => {
  if (!params.postId || params.postId <= 0) {
    const errMsg = '帖子ID无效';
    ElMessage.error(errMsg);
    throw new Error(errMsg);
  }

  try {
    // 调用接口（路径：/likes/toggle，POST方法）
    // 注意：response已经是response.data了
    const response = await api.post<BaseResponse<LikeBusinessData>>(`/likes/toggle`, {
      type: 0,              // 0=帖子类型
      objId: params.postId  // 帖子ID
    });

    // 修复：直接访问response.code，而不是response.data.code
    if (response.code !== "0") {
      const errMsg = response.message || '点赞操作失败';
      ElMessage.error(errMsg);
      throw new Error(errMsg);
    }

    // 修复：直接返回response.data
    return response.data || {
      liked: false,
      likeCount: 0,
      type: 0,
      objId: params.postId
    };
  } catch (error) {
    console.error(`likePost 失败（ID: ${params.postId}）:`, error);
    throw error;
  }
};

/**
 * 获取全部分类（用于筛选栏、发布帖子等场景）
 * @returns 分类列表（Category类型数组）
 */
export const getCategories = async (): Promise<Category[]> => {
  try {
    // 由于拦截器配置，response已经是请求体json对象，不需要再.data
    const response = await api.get<BaseResponse<Category[]>>('/public/categorys');

    if (!response?.success || response?.code !== '0') {
      const errMsg = response?.message || '获取分类列表失败';
      ElMessage.error(errMsg);
      console.error('getCategories 失败:', errMsg);
      // 降级返回默认分类（避免前端筛选栏为空）
      return [
        { cateId: 1, cateName: '科技', createTime: '', updateTime: '' },
        { cateId: 2, cateName: '艺术', createTime: '', updateTime: '' },
        { cateId: 3, cateName: '生活', createTime: '', updateTime: '' },
        { cateId: 4, cateName: '技术讨论', createTime: '', updateTime: '' },
        { cateId: 5, cateName: '问答求助', createTime: '', updateTime: '' }
      ];
    }

    // 兜底防止data为undefined
    return response?.data || [];
  } catch (error) {
    console.error('getCategories 网络错误:', error);
    ElMessage.error('网络异常，获取分类失败');
    // 降级返回默认分类
    return [
      { cateId: 1, cateName: '科技', createTime: '', updateTime: '' },
      { cateId: 2, cateName: '艺术', createTime: '', updateTime: '' },
      { cateId: 3, cateName: '生活', createTime: '', updateTime: '' },
      { cateId: 4, cateName: '技术讨论', createTime: '', updateTime: '' },
      { cateId: 5, cateName: '问答求助', createTime: '', updateTime: '' }
    ];
  }
};

/**
 * 发布新帖子
 * @param postData 帖子内容（分类ID、标题、内容、图片等）
 * @returns 接口返回结果（含新增帖子信息）
 */
export const createPost = async (postData: {
  cateId: number;        // 分类ID（必传）
  title: string;         // 标题（必传）
  content: string;       // 内容（必传，支持HTML）
  media?: string[];      // 图片URL数组（可选）
}): Promise<BaseResponse<Post>> => {
  // 基础参数校验
  if (!postData.cateId || postData.cateId <= 0) {
    throw new Error('请选择帖子分类');
  }
  if (!postData.title.trim()) {
    throw new Error('帖子标题不能为空');
  }
  if (!postData.content.trim()) {
    throw new Error('帖子内容不能为空');
  }

  try {
    // 由于拦截器配置，response已经是请求体json对象，不需要再.data
    const response = await api.post<BaseResponse<Post>>('/posts', postData);

    // 提示用户结果
    if (response?.success && response?.code === '0') {
    } else {
      const errMsg = response?.message || '帖子发布失败';
      ElMessage.error(errMsg);
      throw new Error(errMsg);
    }

    return response || {
      code: '1',
      message: '获取帖子发布结果失败',
      data: {} as Post,
      requestId: null,
      success: false,
      fail: true
    };
  } catch (error) {
    console.error('createPost 失败:', error);
    throw error;
  }
};

/**
 * 收藏列表接口返回的业务数据类型
 */
export interface FavoritesBusinessData {
  posts: Post[];        // 收藏的帖子数组
  size: number;         // 每页大小
  lastId: number;       // 本次查询的最后帖子的id
}

/**
 * 收藏列表接口的返回类型（顶层是 BaseResponse，data 是 FavoritesBusinessData）
 */
export type GetFavoritesRes = BaseResponse<FavoritesBusinessData>;

/**
 * 获取当前用户收藏的帖子列表
 * @param params 查询参数（支持分页）
 * @returns 收藏帖子数组（Post类型）
 */
export const getFavorites = async (params?: {
  size?: number;        // 一页大小（可选，默认10）
  lastId?: number;      // 上次查询的最小时间（可选，默认0）
}): Promise<Post[]> => {
  try {
    // 调用接口（路径：/collections/list，GET方法）
    const response = await api.get<GetFavoritesRes>('/collections/list', {
      params: {
        size: params?.size || 10,
        lastId: params?.lastId || 0
      }
    });

    if (!response.success || response.code !== '0') {
      const errMsg = response.message || '获取收藏列表失败';
      ElMessage.error(errMsg);
      console.error('getFavorites 失败:', errMsg);
      return [];
    }

    // 从响应中提取帖子数组
    return response.data?.posts || [];
  } catch (error) {
    console.error('getFavorites 网络错误:', error);
    ElMessage.error('网络异常，获取收藏列表失败');
    return [];
  }
};

// ------------------------------
// 5. 评论相关核心接口（与后端接口路径、参数完全对齐）
// ------------------------------
/**
 * 获取帖子的评论列表（支持分页续加载）
 * @param params 评论查询参数（必含postId）
 * @returns 评论列表+分页信息（GetCommentsRes类型）
 */
export const getComments = async (params: {
  postId: number;        // 所属帖子ID（必传）
  lastTime?: string;     // 上一页最后一条评论时间（可选，续加载用）
  offset?: number;       // 偏移量（可选，续加载用）
  size?: number;         // 每页条数（可选，默认10）
}): Promise<GetCommentsRes> => {
  if (!params.postId || params.postId <= 0) {
    const errMsg = '帖子ID无效，无法获取评论';
    ElMessage.error(errMsg);
    console.error('getComments 参数错误:', errMsg);
    // 降级返回空评论列表
    return {
      code: '1',
      message: errMsg,
      data: { commentVOS: [], lastTime: '', offset: 0, count: 0 },
      requestId: null,
      success: false,
      fail: true
    };
  }

  try {
    // 构造请求参数（默认值处理）
    const requestParams = {
      postId: params.postId,
      lastTime: params.lastTime || '',
      offset: params.offset || 0,
      size: params.size || 10
    };

    // 调用接口（路径：/public/comments）
    // 由于拦截器配置，response已经是请求体json对象，不需要再.data
    const response = await api.get<GetCommentsRes>('/public/comments', { params: requestParams });

    // 打印调试日志
    if (response?.success) {
      console.log('getComments 成功:', {
        postId: params.postId,
        commentCount: response.data?.commentVOS.length || 0,
        total: response.data?.count || 0
      });
    } else {
      const errMsg = response?.message || '获取评论列表失败';
      ElMessage.error(errMsg);
      console.error('getComments 接口失败:', errMsg, 'requestId:', response?.requestId);
    }

    return response || {
      code: '1',
      message: '获取评论列表数据失败',
      data: { commentVOS: [], lastTime: '', offset: 0, count: 0 },
      requestId: null,
      success: false,
      fail: true
    };
  } catch (error) {
    console.error('getComments 网络错误:', error);
    ElMessage.error('网络异常，获取评论失败');
    // 降级返回空评论列表
    return {
      code: '1',
      message: '网络异常，获取评论失败',
      data: { commentVOS: [], lastTime: '', offset: 0, count: 0 },
      requestId: null,
      success: false,
      fail: true
    };
  }
};

/**
 * 提交评论/回复（一级评论/二级回复通用）
 * @param params 评论参数（pid存在则为回复，否则为一级评论）
 * @returns 提交结果（含新增的评论/回复信息）
 */
export const addComment = async (params: {
  postId: number;        // 所属帖子ID（必传）
  content: string;       // 评论/回复内容（必传）
  pid?: number;          // 父评论ID（可选，回复时必传）
  toUid?: number;        // 被回复者ID（可选，回复时必传）
}): Promise<AddCommentRes> => {
  // 基础参数校验
  if (!params.postId || params.postId <= 0) {
    throw new Error('帖子ID无效');
  }
  const contentTrimmed = params.content.trim();
  if (!contentTrimmed) {
    throw new Error('评论内容不能为空');
  }
  // 回复时必须传pid和toUid
  if (params.pid !== undefined && (!params.pid || params.toUid === undefined)) {
    throw new Error('回复时必须指定父评论ID和被回复者ID');
  }

  try {
    // 构造请求体
    const requestBody = {
      postId: params.postId,
      content: contentTrimmed,
      ...(params.pid && { pid: params.pid }),
      ...(params.toUid !== undefined && { toUid: params.toUid })
    };

    // 调用接口（路径：/comment/create）
    const response = await api.post<BaseResponse<any>>('/comment/create', requestBody);

    // 正确访问响应体
    const responseBody = response;
    
    // 检查响应数据
    if (!responseBody || !responseBody.data) {
      const errMsg = responseBody?.message || (params.pid ? '回复发表失败' : '评论发表失败');
      throw new Error(errMsg);
    }

    // 构造返回数据以兼容现有代码
    const commentDO = responseBody.data;
    const result: AddCommentRes = {
      code: responseBody.code || '0',
      message: responseBody.message || '发表成功',
      data: {
        comment: {
          id: commentDO.id || 0,
          pid: commentDO.pid,
          uid: commentDO.uid || 0,
          toUid: commentDO.toUid,
          postId: commentDO.postId || 0,
          content: commentDO.content || '',
          likeCount: commentDO.likeCount || 0,
          status: commentDO.status || 1,
          createTime: commentDO.createTime || new Date().toISOString(),
          updateTime: commentDO.updateTime || new Date().toISOString(),
          userRespDTO: {
            uid: commentDO.uid || 0,
            loginId: 'current_user',
            nickname: '当前用户',
            avatar: null,
            intro: '这个人很懒，没留下什么'
          },
          liked: false,
          replies: []
        },
        commentId: commentDO.id
      },
      requestId: responseBody.requestId || '',
      success: responseBody.success || true,
      fail: responseBody.fail || false
    };

    return result;
  } catch (error) {
    console.error(`addComment 失败（postId: ${params.postId}，pid: ${params.pid}）:`, error);
    throw error;
  }
};

/**
 * 评论/回复点赞/取消点赞（通用）
 * @param params 点赞参数（评论ID+点赞状态）
 * @returns 点赞结果（含最新状态和点赞数）
 */
export const likeComment = async (params: {
  commentId: number;     // 评论/回复ID（必传）
  isLike: boolean;       // 点赞状态（true=点赞，false=取消）
}): Promise<LikeBusinessData> => {
  if (!params.commentId || params.commentId <= 0) {
    const errMsg = '评论ID无效';
    ElMessage.error(errMsg);
    throw new Error(errMsg);
  }

  try {
    // 调用接口（路径：/comments/{commentId}/like，POST方法）
    const response = await api.post<LikeRes>(`/comments/${params.commentId}/like`, {
      isLike: params.isLike
    });
    
    // 正确访问响应体
    const responseBody = response.data;

    if (!responseBody || !responseBody.success || responseBody.code !== '0') {
      const errMsg = responseBody?.message || (params.isLike ? '评论点赞失败' : '取消评论点赞失败');
      ElMessage.error(errMsg);
      throw new Error(errMsg);
    }

    return responseBody.data || { liked: params.isLike, likeCount: 0 };
  } catch (error) {
    console.error(`likeComment 失败（ID: ${params.commentId}，isLike: ${params.isLike}）:`, error);
    throw error;
  }
};

/**
 * 删除评论/回复（通用）
 * @param commentId 评论/回复ID（必传）
 * @returns 接口返回结果（BaseResponse类型）
 */
export const deleteComment = async (commentId: number) => {
  if (!commentId || commentId <= 0) {
    const errMsg = '评论ID无效';
    ElMessage.error(errMsg);
    throw new Error(errMsg);
  }

  try {
    // 调用接口（路径：/comments/{commentId}，DELETE方法）
    const response = await api.delete<BaseResponse>(`/comments/${commentId}`);
    
    // 正确访问响应体
    const responseBody = response;

    if (responseBody && responseBody.success && responseBody.code === '0') {
      ElMessage.success('删除成功');
    } else {
      const errMsg = responseBody?.message || '删除失败';
      throw new Error(errMsg);
    }

    return responseBody;
  } catch (error) {
    console.error(`deleteComment 失败（ID: ${commentId}）:`, error);
    throw error;
  }
};

// ------------------------------
// 6. 辅助工具函数（可选，用于简化前端逻辑）
// ------------------------------
/**
 * 格式化时间为"多久前"（适配后端时间格式如"2025-09-05 21:25:52"）
 * @param dateString 后端返回的时间字符串
 * @returns 格式化后的时间（如"1小时前"）
 */
export const formatRelativeTime = (dateString: string): string => {
  if (!dateString) return '未知时间';

  try {
    // 处理后端时间格式（兼容"2025-09-05 21:25:52"和"2025-09-05T21:25:52"）
    const normalizedDate = new Date(dateString.replace(' ', 'T'));
    const now = new Date();
    const diffInMs = now.getTime() - normalizedDate.getTime();

    // 计算不同时间单位
    const second = 1000;
    const minute = second * 60;
    const hour = minute * 60;
    const day = hour * 24;
    const week = day * 7;

    if (diffInMs < minute) {
      return `${Math.floor(diffInMs / second)}秒前`;
    } else if (diffInMs < hour) {
      return `${Math.floor(diffInMs / minute)}分钟前`;
    } else if (diffInMs < day) {
      return `${Math.floor(diffInMs / hour)}小时前`;
    } else if (diffInMs < week) {
      return `${Math.floor(diffInMs / day)}天前`;
    } else {
      // 超过一周显示具体日期（如"2025-09-05"）
      return normalizedDate.toLocaleDateString('zh-CN');
    }
  } catch (error) {
    console.warn('时间格式化失败:', error, '原始时间:', dateString);
    // 失败时返回原始时间的前10位（如"2025-09-05"）
    return dateString.slice(0, 10);
  }
};

/**
 * 获取用户头像（兜底处理null/空字符串）
 * @param avatar 后端返回的头像URL
 * @returns 安全的头像URL（含默认图）
 */
export const getSafeAvatar = (avatar: string | null | undefined): string => {
  if (avatar && avatar.trim()) {
    return avatar.trim();
  }
  // 默认头像（使用picsum固定seed，保证同一用户显示同一默认图）
  return 'https://ts2.tc.mm.bing.net/th/id/OIP-C.U5eWqyIFDzu2Lb_wWg98sAHaLc?rs=1&pid=ImgDetMain&o=7&rm=3';
};

/**
 * 获取用户名（兜底处理null/空字符串，优先nickname，其次loginId）
 * @param user 用户信息（UserBaseInfo类型）
 * @returns 安全的用户名
 */
export const getSafeUserName = (user: UserBaseInfo): string => {
  if (user.nickname && user.nickname.trim()) {
    return user.nickname.trim();
  }
  if (user.loginId && user.loginId.trim()) {
    return user.loginId.trim();
  }
  return '匿名用户';
};

// ------------------------------
// 7. 帖子管理相关接口
// ------------------------------
/**
 * 删除帖子
 * @param postId 帖子ID（必传）
 * @returns 接口返回结果（BaseResponse类型）
 */
export const deletePost = async (postId: number) => {
  if (!postId || postId <= 0) {
    const errMsg = '帖子ID无效';
    ElMessage.error(errMsg);
    throw new Error(errMsg);
  }

  try {
    // 调用接口（路径：/posts/{postId}，DELETE方法）
    const response = await api.delete<BaseResponse>(`/posts/${postId}`);
    
    // 正确访问响应体
    const responseBody = response;

    if (responseBody && responseBody.success && responseBody.code === '0') {
      
    } else {
      const errMsg = responseBody?.message || '删除失败';
      ElMessage.error(errMsg);
      throw new Error(errMsg);
    }

    return responseBody;
  } catch (error) {
    console.error(`deletePost 失败（ID: ${postId}）:`, error);
    throw error;
  }
};

/**
 * 获取指定评论的回复列表（支持分页续加载）
 * @param commentId 评论ID
 * @param size 每页大小（默认3）
 * @param lastTime 上次查询的最小时间（用于分页）
 * @param offset 上次查询时间为最小值的个数（用于分页）
 * @returns 回复列表和分页信息
 */
export const getCommentReplies = async (commentId: number, size: number = 3, lastTime?: string, offset?: number): Promise<{
  data: Comment[];
  lastTime?: string;
  offset?: number;
  count?: number;
}> => {
  if (!commentId || commentId <= 0) {
    const errMsg = '评论ID无效';
    ElMessage.error(errMsg);
    throw new Error(errMsg);
  }

  try {
    // 构造请求参数
    const params = new URLSearchParams();
    params.append('commentId', commentId.toString());
    params.append('size', size.toString());
    if (lastTime) {
      params.append('lastTime', lastTime);
    }
    if (offset !== undefined) {
      params.append('offset', offset.toString());
    }

    // 调用接口
    const response = await api.get<BaseResponse<CommentPageVO>>('/public/comments/replies', { params });
    
    const responseBody = response;

    if (!responseBody || !responseBody.success || responseBody.code !== '0' || !responseBody.data) {
      const errMsg = responseBody?.message || '获取回复列表失败';
      ElMessage.error(errMsg);
      throw new Error(errMsg);
    }

    return {
      data: responseBody.data.commentVOS || [],
      lastTime: responseBody.data.lastTime,
      offset: responseBody.data.offset,
      count: responseBody.data.count
    };
  } catch (error) {
    console.error(`getCommentReplies 失败（评论ID: ${commentId}）:`, error);
    throw error;
  }
};

// ------------------------------
// 8. 媒体上传相关接口
// ------------------------------
/**
 * 单个媒体文件上传响应数据
 */
export interface SingleMediaUploadResponseData {
  url: string;        // 文件访问URL
  type: string;       // 文件类型
  filename: string;   // 文件名
  size: number;       // 文件大小（字节）
  mimeType: string;   // MIME类型
}

/**
 * 多文件上传响应数据
 */
export interface MediaUploadResponseData {
  data: SingleMediaUploadResponseData[];
}

/**
 * 上传单个媒体文件
 * @param file 要上传的文件
 * @param fileType 文件类型（image/video/audio）
 * @param folder 存储文件夹
 * @returns 上传结果
 */
export const uploadSingleMedia = async (file: File, fileType: string = 'image', folder: string = 'posts'): Promise<SingleMediaUploadResponseData> => {
  if (!file) {
    throw new Error('请选择要上传的文件');
  }

  // 检查文件大小（最大50MB）
  const maxSize = 50 * 1024 * 1024; // 50MB
  if (file.size > maxSize) {
    throw new Error(`文件大小不能超过50MB，当前文件大小：${(file.size / (1024 * 1024)).toFixed(2)}MB`);
  }

  // 检查文件类型
  const validTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
  if (!validTypes.includes(file.type)) {
    throw new Error('不支持的文件类型，仅支持JPG、PNG、GIF、WebP格式');
  }

  try {
    const formData = new FormData();
    formData.append('file', file);
    formData.append('type', fileType);
    formData.append('folder', folder);

    // 由于拦截器配置，response已经是请求体json对象，不需要再.data
    const response = await api.post<BaseResponse<SingleMediaUploadResponseData>>('/media/upload/single', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });

    if (!response?.success || response?.code !== '0' || !response?.data) {
      const errMsg = response?.message || '文件上传失败';
      ElMessage.error(errMsg);
      throw new Error(errMsg);
    }

    return response.data;
  } catch (error) {
    console.error('上传单个媒体文件失败:', error);
    throw error;
  }
};

/**
 * 上传多个媒体文件
 * @param files 要上传的文件数组
 * @param fileType 文件类型
 * @param folder 存储文件夹
 * @returns 上传的图片URL数组
 */
export const uploadMultipleMedia = async (files: File[], fileType: string = 'image', folder: string = 'posts'): Promise<string[]> => {
  if (!files || files.length === 0) {
    throw new Error('请选择要上传的文件');
  }

  // 检查文件数量（最多9个）
  if (files.length > 9) {
    throw new Error('最多支持上传9个文件');
  }

  try {
    const formData = new FormData();
    files.forEach(file => formData.append('files', file));
    formData.append('type', fileType);
    formData.append('folder', folder);

    // 由于拦截器配置，response已经是请求体json对象，不需要再.data
    const response = await api.post<BaseResponse<SingleMediaUploadResponseData[]>>('/media/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    });

    if (!response?.success || response?.code !== '0' || !response?.data) {
      const errMsg = response?.message || '文件上传失败';
      ElMessage.error(errMsg);
      throw new Error(errMsg);
    }

    // 只返回图片URL数组，便于发帖时直接使用
    return response.data.map(item => item.url);
  } catch (error) {
    console.error('上传多个媒体文件失败:', error);
    throw error;
  }
};

// 在文件末尾添加以下代码

/**
 * 用户统计数据类型（用于个人中心展示）
 */
export interface UserStats {
  posts: number;        // 发布的帖子数量
  following: number;    // 关注数量
  followers: number;    // 粉丝数量
  collections: number;  // 收藏数量
}

/**
 * 获取用户统计数据
 * @param uid 用户ID（可选，不传则获取当前登录用户的统计数据）
 * @returns 用户统计数据
 */
export const getUserStats = async (uid?: number): Promise<UserStats> => {
  try {
    // 构造请求参数
    const requestParams = uid ? { uid } : {};
    // 调用接口（路径假设为 /user/stats，需与后端确认）
    const response = await api.get<BaseResponse<UserStats>>('/user/stats', { params: requestParams });
    
    if (!response.data?.success || response.data?.code !== '0') {
      const errMsg = response.data?.message || '获取用户统计数据失败';
      console.error('getUserStats 失败:', errMsg);
      // 降级返回默认数据
      return { posts: 0, following: 0, followers: 0, collections: 0 };
    }
    
    return response.data?.data || { posts: 0, following: 0, followers: 0, collections: 0 };
  } catch (error) {
    console.error('getUserStats 网络错误:', error);
    // 降级返回默认数据
    return { posts: 0, following: 0, followers: 0, collections: 0 };
  }
};

/**
 * 获取用户发布的帖子列表
 * @param params 查询参数
 * @returns 用户发布的帖子列表和分页信息
 */
export const getUserPosts = async (params: {
  uid: number;          // 用户ID（必传）
  size?: number;        // 每页条数（可选，默认10）
  lastId?: number | null; // 上一页最后一条ID（可选，续加载用）
}): Promise<{
  data: PostsListBackendData;
  hasMore: boolean;
}> => {
  // 复用 getPosts 函数，指定 uid 参数
  return getPosts({
    uid: params.uid,
    size: params.size,
    lastId: params.lastId
  });
};